package javax.per.toolkit.xml;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.SAXException;

/**
 * Test for writing XML file with SAX
 * @author yl34569
 */

public class SAXWriter {
	
	private String xmlPath="src/aaa.xml";
	private TransformerHandler handler=null;
	private SAXTransformerFactory factory=null;
	private String root=null;
	
	/**
	 * Set the root element of the xml file
	 * @param root name of the root element
	 */
	public void setRoot(String root) {
		this.root = root;
	}
	
	/**
	 * Set xml file path
	 * @param xmlPath path of the xml file
	 */
	public void setXmlPath(String xmlPath) {
		this.xmlPath = xmlPath;
	}


	/**
	 * Do something to initialize<br/>
	 * should be invoke after set xml file path
	 * @throws TransformerConfigurationException
	 * @throws FileNotFoundException
	 */
	public void init() throws TransformerConfigurationException, FileNotFoundException{
		factory=(SAXTransformerFactory) SAXTransformerFactory.newInstance();
		handler=factory.newTransformerHandler();
		Transformer trans=factory.newTransformer();
		trans.setOutputProperty(OutputKeys.ENCODING, "utf-8");
		trans.setOutputProperty(OutputKeys.INDENT, "yes");
		if(!(new File(xmlPath).exists()))
			throw new Error();
		OutputStream os=new FileOutputStream(xmlPath);
		handler.setResult(new StreamResult(os));
		
	}
	
	/**
	 * Start to write xml file
	 * @throws SAXException
	 */
	public void start() throws SAXException{
		if(root==null)
			throw new Error();
		handler.startDocument();
		handler.startElement("", "", root, null);
	}
	
	
	/**
	 * End to write xml file
	 * @throws SAXException
	 */
	public void end() throws SAXException{
		if(root==null)
			throw new Error();
		handler.endElement("", "", root);
		handler.endDocument();
	}
	
	/**
	 * Write data to xml file
	 * @param map a map contains elements inner 
	 * @param element the name of the outer element
	 * @throws SAXException
	 */
	public void write(HashMap<String,String> map,String element) throws SAXException{
		handler.startElement("", "", element, null);
		Iterator<String> it=map.keySet().iterator();
		while(it.hasNext()){
			String key=it.next();
			String value=map.get(key);
			handler.startElement("", "", key, null);
			handler.characters(value.toCharArray(), 0, value.getBytes().length);
			handler.endElement("", "", key);
		}
		handler.endElement("", "", element);
	}

	
	/**
	 * Test code
	 * @param args command line
	 * @throws Exception
	 * @throws FileNotFoundException
	 */
	public static void main(String[] args) throws Exception, FileNotFoundException {
		
		SAXWriter test=new SAXWriter();
		test.init();
		test.setRoot("books");
		test.start();
		HashMap<String,String> map=new HashMap<String,String>();
		byte ch='a';
		for(ch='a';ch<'e';ch++){
			byte[] buf=new byte[4];
			for(int i=0;i<buf.length;i++)
				buf[i]=ch;
			map.put(new String(buf), new String(buf));
		}
		test.write(map, "book");
		test.write(map, "book");
		test.end();
	}

}
